# coding=utf-8
"""

5. 使用棋盘格及自选风景图像，分别使用SIFT、FAST及ORB算子检测角点，并比较分析检测结果。
(可选)使用Harris角点检测算子检测棋盘格，并与上述结果比较。
结果分析:
1) SIFT: SIFT旋转检测较为精准，但是检测速度较慢，相对的角点检测效果很好，之后的很多角点检测算子都是根据SIFT角点检测提出的，并且进行了提速等优化。
2) FAST: FAST算法算法速度较快，由SIFT算法改进而来，抗噪声的能力相对较弱，角点判断容易出错。FAST的提出者 Rosten 等将FAST角点定义为：若某像素与其周围邻域内足够多的像素点相差较大，则该像素可能是角点。
3) ORB: ORB算法检测速度较快效果也精准，ORB = oFAST + rBRIEF (oFAST是由FAST算法改进)，在使用oFAST提取出特征点之后，为其定义一个特征点方向，以此来实现特征点的旋转不变性。
4) Harris 角点检测效果也还不错，但也存在很多漏检的角。
5）从代码运行结果来看，FAST 角点检测误检比较多，但基本上所以的角点都检测出来了，SIFT 角点检测效果要略好于 FAST，而 ORB 的角点检测是基于改进的 FAST，所以检测效果要好一点，但存在漏检的情况。Harris与前三者相比，效果与速度都介于中间可接受范围。

"""
# SIFT
"""
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

ChessboardFilename = r'left03.jpg'
BuildingFilename = r'St_MaryHelpChristiansChurch-185.jpg'
sift = cv.xfeatures2d.SIFT_create()
sift2 = cv.xfeatures2d.SIFT_create()
img = cv.imread(ChessboardFilename)
img2 = cv.imread(BuildingFilename)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
gray2 = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)
kp, des = sift.detectAndCompute(img, None)
kp2, des2 = sift2.detectAndCompute(img2, None)
plt.figure(figsize=(15, 15))
plt.subplot(2, 2, 1)
plt.title("Chessboard_gray")
plt.imshow(gray, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_1.JPG
plt.subplot(2, 2, 3)
plt.title("Building_gray")
plt.imshow(gray2, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_1.JPG

# cv2.imshow('gray',gray)
# cv2.waitKey(0)

img1 = cv.drawKeypoints(img, kp, img, color=(255, 0, 255))
img3 = cv.drawKeypoints(img2, kp2, img2, color=(255, 0, 255))
plt.subplot(2, 2, 2), plt.title("Chessboard_points")
plt.imshow(img1)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_1.JPG
plt.subplot(2, 2, 4), plt.title("Building_points")
plt.imshow(img3)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_1.JPG
plt.show()
"""

# FAST
"""
import cv2 as cv
import matplotlib.pyplot as plt

ChessboardFilename = r'left03.jpg'
BuildingFilename = r'St_MaryHelpChristiansChurch-185.jpg'
cimg = cv.imread(ChessboardFilename)
bimg = cv.imread(BuildingFilename)
fast = cv.FastFeatureDetector_create()
# fast_1 = cv.FastFeatureDetector_create()
kp_c = fast.detect(cimg, None)
kp_b = fast.detect(bimg, None)
cimg_kp = cv.drawKeypoints(cimg, kp_c, None, color=(255, 0, 0))
bimg_kp = cv.drawKeypoints(bimg, kp_b, None, color=(255, 0, 0))
# fast.setNonmaxSuppression(0)  # 这个是取消fast算法里面的非极大值抑制
# kp = fast.detect(img,None)
# img2 = cv.drawKeypoints(img, kp, None, color=(255,0,0))
plt.figure(figsize=(15,15))
plt.subplot(2, 2, 1)，plt.title("Chessboard_Gray")
plt.imshow(cimg, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_2.JPG
plt.subplot(2, 2, 2), plt.title("Chessboard_FAST")
plt.imshow(cimg_kp)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_2.JPG
plt.subplot(2, 2, 3), plt.title("Building_Gray")
plt.imshow(bimg, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_2.JPG
plt.subplot(2, 2, 4), plt.title("Buliding_FAST")
plt.imshow(bimg_kp)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_2.JPG
plt.show()
"""

# ORB
"""
import cv2 as cv
import matplotlib.pyplot as plt

ChessboardFilename = r'left03.jpg'
BuildingFilename = r'St_MaryHelpChristiansChurch-185.jpg'
bimg = cv.imread(BuildingFilename, cv.IMREAD_GRAYSCALE)
cimg = cv.imread(ChessboardFilename, cv.IMREAD_GRAYSCALE)
orb = cv.ORB_create()
# fast_1 = cv.FastFeatureDetector_create()
kp_c, dest_c = orb.detectAndCompute(cimg, None)
kp_b, dest_b = orb.detectAndCompute(bimg, None)
cimg_kp = cv.drawKeypoints(cimg, kp_c, None, color=(255, 0, 255))
bimg_kp = cv.drawKeypoints(bimg, kp_b, None, color=(255, 0, 255))
# fast.setNonmaxSuppression(0)  # 这个是取消fast算法里面的非极大值抑制
# kp = fast.detect(img,None)
# img2 = cv.drawKeypoints(img, kp, None, color=(255,0,0))
plt.figure(figsize=(15,15))
plt.subplot(2, 2, 1), plt.title("Chessboard_Gray")
plt.imshow(cimg, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_3.JPG
plt.subplot(2, 2, 2), plt.title("Chessboard_ORB")
plt.imshow(cimg_kp)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_3.JPG
plt.subplot(2, 2, 3),plt.title("Building_Gray")
plt.imshow(bimg, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_3.JPG
plt.subplot(2, 2, 4),plt.title("Buliding_ORB")
plt.imshow(bimg_kp)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_3.JPG
plt.show()
"""

# Harris

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

ChessboardFilename = r'left03.jpg'
BuildingFilename = r'St_MaryHelpChristiansChurch-185.jpg'
cimg = cv.imread(ChessboardFilename)
#bimg = cv.imread(BuildingFilename)
cgray = cv.cvtColor(cimg, cv.COLOR_BGR2GRAY)
#bgray = cv.cvtColor(bimg, cv.COLOR_BGR2GRAY)

#图像转换为 float32
cgray = np.float32(cgray)
#bgray = np.float32(bgray)

dst_c = cv.cornerHarris(cgray, 2, 3, 0.06)   # 0.04是角点响应函数里面的系数，属于经验值一般取0.04-0.06
#dst_b = cv.cornerHarris(bgray, 2, 3, 0.06)

#cv.imshow("Chessboard_Harris", dst_c)
#cv.imshow("Building_Harris", dst_b)
#cv.waitKey()
#cv.destroyAllWindows()  # 直接用Harris角点检测出来的图基本上看不到什么，所以需要进行进一步处理

dst_c = cv.dilate(dst_c, None)  # 图像膨胀 目的是把角点的标记变大些
dst_c = cv.dilate(dst_c, None)
#dst_b = cv.dilate(dst_b, None)
#dst_b = cv.dilate(dst_b, None)

# 这里以大于 0.1*dst 中最大值为边界
cimg[dst_c > 0.1*dst_c.max()] = [255, 0, 0]  # 角点位置用红色标记
#bimg[dst_b > 0.01*dst_b.max()]=[255, 0, 0]  # 角点位置用红色标记

plt.figure(figsize=(15, 15))
plt.subplot(2, 2, 1), plt.title("Chessboard_Gray")
plt.imshow(cgray, cmap="gray")  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_4.JPG
plt.subplot(2, 2, 2), plt.title("Chessboard_Harris")
plt.imshow(cimg)  # 运行结果:  https://gitee.com/skyrookieyu/csdn_ai25_week2/blob/master/5_4.JPG
plt.show()
